package com.dsteiner.xelavos.client.controller;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Date;

import org.apache.commons.httpclient.util.DateUtil;

import com.dsteiner.widgets.client.DateUtilImpl;
import com.dsteiner.widgets.client.IJsUtil;
import com.dsteiner.widgets.client.JsUtil;
import com.dsteiner.widgets.client.StringUtil;
import com.dsteiner.widgets.client.Widgets.ILazyWidget;
import com.dsteiner.widgets.client.Widgets.IWidget;
import com.dsteiner.widgets.client.Widgets.WidgetListenerAdapter;
import com.dsteiner.widgets.client.domain.ModelObject;
import com.dsteiner.widgets.client.domain.Sort;
import com.dsteiner.widgets.client.model.PrefilledTextBoxModel;
import com.dsteiner.widgets.client.model.SuggestBoxModel;
import com.dsteiner.widgets.client.model.SuggestionModel;
import com.dsteiner.widgets.client.rpc.SearchResult;
import com.dsteiner.widgets.client.rpc.SearchRequest.SearchRequestImpl;
import com.dsteiner.xelavos.client.constants.Constants;
import com.dsteiner.xelavos.client.domain.Product;
import com.dsteiner.xelavos.client.model.CreateObjectModel;
import com.dsteiner.xelavos.client.rpc.DataService;
import com.google.appengine.api.datastore.Text;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class CreateProductController implements IModelObjectBuilder{

	private PrefilledTextBoxModel descriptionTextBoxModel;
	private PrefilledTextBoxModel brandTextBoxModel;
	private PrefilledTextBoxModel modelTextBoxModel;
	private PrefilledTextBoxModel nameTextBoxModel;
	private PrefilledTextBoxModel priceTextBoxModel;
	private SuggestBoxModel shopTextBoxModel;
	private PrefilledTextBoxModel contactTextBoxModel;
	private CreateObjectModel createObjectModel;
	private PrefilledTextBoxModel validUntilTextBoxModel;
	private IJsUtil jsUtil;

	public ModelObject create() {
		String name = nameTextBoxModel.getText();
		String shop = shopTextBoxModel.isEdited() ? shopTextBoxModel.getText() : null;
		String model = modelTextBoxModel.isEdited() ? modelTextBoxModel.getText() : null;
		String brand = brandTextBoxModel.isEdited() ? brandTextBoxModel.getText() : null;
		String description = descriptionTextBoxModel.isEdited() ? descriptionTextBoxModel.getText() : null;
		String contact = contactTextBoxModel.isEdited() ? contactTextBoxModel.getText() : null;
		Date validUntil = DateUtilImpl.parseDate(validUntilTextBoxModel.isEdited() ? validUntilTextBoxModel.getText() : null, DateUtilImpl.formatterSpanish);
		String price = priceTextBoxModel.getText();
		Double priceAsDouble = null;
		
		nameTextBoxModel.setHasError(false);
		priceTextBoxModel.setHasError(false);
		
		StringBuffer text = new StringBuffer();
		if(!nameTextBoxModel.isEdited()){
			text.append("ingrese un nombre\n");
			nameTextBoxModel.setHasError(true);
		}
		if(priceTextBoxModel.isEdited()) {
			try{
				price = price.replace("Q", "").replace(",", "");
				priceAsDouble = Double.parseDouble(price);
			}catch(Exception ex){
				text.append("ingrese el precio como numero");
				priceTextBoxModel.setHasError(true);
			}
		}
		
		if(text.length() > 0){
			jsUtil.trackEvent(Constants.CAT_PUBLISHING, Constants.ACT_MSG_SHOWN, text.toString());
			JsUtil.getInstance().showAlert(text.toString());
			return null;
		}

		Product product = new Product();
		if(createObjectModel.getCreateModelObject() != null)
			product = (Product) createObjectModel.getCreateModelObject();
		product.setName(name);
		product.setShop(shop);
		product.setPrice(priceAsDouble);
		product.setBrand(brand);
		product.setModel(model);
		product.setDescription(description != null ? new Text(description) : null);
		product.setRegisteredDate(new Date());
		product.setContact(contact);
		product.setValidUntilDate(validUntil);
		
		return product;
	}

	public void registerBrandTextBoxModel(final PrefilledTextBoxModel brandTextBoxModel) {
		this.brandTextBoxModel = brandTextBoxModel;
		brandTextBoxModel.addPropertyChangeListener("hasFocus", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				if(!brandTextBoxModel.hasFocus())
					updateImageSearch();
			}
		});
	}

	public void registerContactTextBoxModel(PrefilledTextBoxModel contactTextBoxModel) {
		this.contactTextBoxModel = contactTextBoxModel;
	}

	public void registerCreateObjectModel(CreateObjectModel createObjectModel) {
		this.createObjectModel = createObjectModel;
		createObjectModel.addPropertyChangeListener("createModelObject", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				updateUi();
			}
		});
	}

	public void registerCreateObjectWidget(ILazyWidget createObjectWidget) {
		createObjectWidget.addWidgetListener(new WidgetListenerAdapter() {
			@Override
			public void onAttach(IWidget widget) {
				updateUi();
			}
		});
	}

	private void updateUi() {
		ModelObject object = createObjectModel.getCreateModelObject();
		if(object != null && !(object instanceof Product))
			return;
		Product createModelObject = (Product) createObjectModel.getCreateModelObject();
		brandTextBoxModel.setText(createModelObject != null ? createModelObject.getBrand() : null);
		modelTextBoxModel.setText(createModelObject != null ? createModelObject.getModel() : null);
		descriptionTextBoxModel.setText(createModelObject != null ? createModelObject.getDescription() != null ? createModelObject.getDescription().toString() : null : null);
		nameTextBoxModel.setText(createModelObject != null ? createModelObject.getName() : null);
		priceTextBoxModel.setText(createModelObject != null ? createModelObject.getPrice() != null ? createModelObject.getPrice().toString() : null : null);
		shopTextBoxModel.setText(createModelObject != null ? createModelObject.getShop() : null);
		contactTextBoxModel.setText(createModelObject != null ? createModelObject.getContact() : null);
		validUntilTextBoxModel.setText(createModelObject != null ? 
				DateUtilImpl.getInstance().formatDateSpanish(createModelObject.getValidUntilDate()) : null);
		updateImageSearch();
	}

	public void registerDescriptionTextBoxModel(PrefilledTextBoxModel descriptionTextBoxModel) {
		this.descriptionTextBoxModel = descriptionTextBoxModel;
	}

	public void registerModelTextBoxModel(final PrefilledTextBoxModel modelTextBoxModel) {
		this.modelTextBoxModel = modelTextBoxModel;
		modelTextBoxModel.addPropertyChangeListener("hasFocus", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				if(!modelTextBoxModel.hasFocus())
					updateImageSearch();
			}
		});
	}

	public void registerNameTextBoxModel(final PrefilledTextBoxModel nameTextBoxModel) {
		this.nameTextBoxModel = nameTextBoxModel;
		nameTextBoxModel.addPropertyChangeListener("hasFocus", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				if(!nameTextBoxModel.hasFocus())
					updateImageSearch();
			}
		});
	}
	
	public void registerPriceTextBoxModel(PrefilledTextBoxModel priceTextBoxModel) {
		this.priceTextBoxModel = priceTextBoxModel;
	}

	public void registerShopTextBoxModel(final SuggestBoxModel shopTextBoxModel) {
		this.shopTextBoxModel = shopTextBoxModel;
		shopTextBoxModel.addPropertyChangeListener("choosenSuggestion", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				SuggestionModel choosenSuggestion = shopTextBoxModel.getChoosenSuggestion();
				if(choosenSuggestion != null && !contactTextBoxModel.isEdited()){
					SearchRequestImpl searchRequest = new SearchRequestImpl();
					searchRequest.setLimit(5);
					searchRequest.setClassName(Product.class.getName());
					searchRequest.setText(choosenSuggestion.getSuggestion().getDisplayText());
					searchRequest.setSort(new Sort("registeredDate",false));
					DataService.Util.getInstance().search(searchRequest, new AsyncCallback<SearchResult<Product>>(){
						public void onFailure(Throwable caught) {
							caught.printStackTrace();
						}
						public void onSuccess(SearchResult<Product> result) {
							for (Product product : result.getObjects()) {
								String contact = product.getContact();
								if(!StringUtil.isEmpty(contact)){
									contactTextBoxModel.setText(contact);
									break;
								}
							}
						}
					});
				}
			}
		});
	}

	private void updateImageSearch() {
		StringBuffer imageSearch = new StringBuffer("");

		if(nameTextBoxModel.isEdited())
			imageSearch.append(nameTextBoxModel.getText()).append(" ");
		if(brandTextBoxModel.isEdited())
			imageSearch.append(brandTextBoxModel.getText()).append(" ");
		if(modelTextBoxModel.isEdited())
			imageSearch.append(modelTextBoxModel.getText()).append(" ");
		
		createObjectModel.setImageSearch(imageSearch.length() > 0 ? imageSearch.toString() : null);
	}

	public void registerValidUntilTextBoxModel(PrefilledTextBoxModel validUntilTextBoxModel) {
		this.validUntilTextBoxModel = validUntilTextBoxModel;
	}

	public void registerJsUtil(IJsUtil jsUtil) {
		this.jsUtil = jsUtil;
	}
}